package com.nsxy.test;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nsxy.common.config.RootConfig;

/**
 * 测试用例基类
 * @author 潜行的青衣
 * @see
 */
@WebAppConfiguration
@ContextConfiguration(classes = {RootConfig.class})
public abstract class BaseTestNG extends AbstractTestNGSpringContextTests {

	protected final MockHttpServletRequest request = new MockHttpServletRequest();
	
	protected final MockHttpServletResponse response = new MockHttpServletResponse();
	
	protected final MockHttpSession session = new MockHttpSession();
	
	protected final ObjectMapper om = new ObjectMapper();
	
	@Resource
	protected org.apache.shiro.mgt.SecurityManager securityManager;
	
	@BeforeTest
	public void setActionContext() {
		request.setSession(session);
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
	}
	
	@BeforeMethod
	public void bindShiro() {
		//初始化shiro
		DefaultWebSubjectContext context = new DefaultWebSubjectContext();
		context.setServletRequest(request);
		context.setServletResponse(response);
		context.setSecurityManager(securityManager);
		
		Subject subject = securityManager.createSubject(context);
		
		ThreadContext.bind(securityManager);
		ThreadContext.bind(subject);
		
		SecurityUtils.setSecurityManager(securityManager);
	}
	
	protected void login(String username, String password) {
		UsernamePasswordToken authenticationToken = new UsernamePasswordToken(username, password, false);
		SecurityUtils.getSubject().login(authenticationToken);
	}
	
	@AfterMethod
	public void logout() {
		SecurityUtils.getSubject().logout();
		ThreadContext.unbindSecurityManager();
		ThreadContext.unbindSubject();
	}
	
	public String println(Object obj) {
		Assert.assertNotNull(obj);
		String result = null;
		try {
			result = om.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		System.out.println(result);
		return result;
	}
}
